import { In, Repository, Like, Between, Not } from 'typeorm';
import { AppDataSource } from '../../config/database';
import { User, UserStatus, PaymentStatus, AdmissionResult } from '../../entities/User';
import bcrypt from 'bcryptjs';
import authConfig from '../../config/auth';
import { User as UserEntity } from '../../entities/User';
import jwt from 'jsonwebtoken';
import { DecodedToken } from "../../types/auth";
import { JWT_SECRET } from "../../middleware/auth";
import { number } from "zod";
import * as ExcelJS from 'exceljs';
import { v4 as uuidv4 } from 'uuid';
import { SystemMessage, MessageType, MessageStatus } from '../../entities/SystemMessage';
import { PaymentRecord } from '../../entities/PaymentRecord';
import { notificationService } from '../../services/NotificationService';

interface DataItem {
  user_count: string;
  org_id: string | null;
  district_name: string | null;
  role_name: string | null;
  role_id: string | null;
  register_date: string | null;
}

export class UserService {
  private userRepository: Repository<User>;
  private systemMessageRepository: Repository<SystemMessage>;
  private paymentRepository: Repository<PaymentRecord>;

  constructor() {
    this.userRepository = AppDataSource.getRepository(User);
    this.systemMessageRepository = AppDataSource.getRepository(SystemMessage);
    this.paymentRepository = AppDataSource.getRepository(PaymentRecord);
  }

  /**
   * 生成用户ID（TN_随机值12位）
   */
  async generateUserId(): Promise<string> {
    const prefix = 'TN_';
    const uniqueId = uuidv4().replace(/-/g, '').substring(0, 12);
    return `${prefix}${uniqueId}`;
  }

  /**
   * 获取用户列表
   */
  async findAll(query: any = {}): Promise<{ users: User[]; total: number }> {
    const { page = 1, pageSize = 10, ...whereQuery } = query;

    const [users, total] = await this.userRepository.findAndCount({
      where: whereQuery,
      order: { createTime: 'DESC' },
      skip: (page - 1) * pageSize,
      take: pageSize
    });

    return { users, total };
  }

  /**
   * 获取用户详情（包含支付记录）
   */
  async getUserDetail(id: string): Promise<{ user: User | null, payments: PaymentRecord[] }> {
    const user = await this.userRepository.findOne({
      where: { id } 
    });
    
    // 获取用户的支付记录
    const payments = user ? await this.paymentRepository.find({
      where: { userId: id },
      order: { createTime: 'DESC' }
    }) : [];
    
    return { user, payments };
  }

  /**
   * 根据ID获取用户
   */
  async findById(id: string): Promise<User | null> {
    return await this.userRepository.findOne({ where: { id } });
  }

  /**
   * 创建用户
   */
  async create(userData: Partial<User>): Promise<User> {
    // 开启事务
    const queryRunner = AppDataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
        // 检查身份证是否存在
      if (userData.idCard) {
        const existingUser = await queryRunner.manager.findOne(User, {
          where: { idCard: userData.idCard }
        });

        if (existingUser) {
          throw { status: 400, message: '身份证号已被使用' };
        }
      }

      // 检查手机号是否存在
      if (userData.mobile) {
        const mobileUser = await queryRunner.manager.findOne(User, {
          where: { mobile: userData.mobile }
        });

      if (mobileUser) {
        throw { status: 400, message: '手机号已被使用' };
      }
      }

      // 设置创建时间
      userData.createTime = new Date();
      userData.updateTime = new Date();

      // 创建用户
      const user = await queryRunner.manager.save(User, userData);
      await queryRunner.commitTransaction();

      return user;
    } catch (error) {
      await queryRunner.rollbackTransaction();
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 更新用户
   */
  async update(id: string, updateData: Partial<User>): Promise<User | null> {
    const user = await this.findById(id);
    if (!user) {
      return null;
    }

    // 检查手机号是否被占用
    if (updateData.mobile && updateData.mobile !== user.mobile) {
      const existingUser = await this.userRepository.findOne({
        where: { mobile: updateData.mobile }
      });

      if (existingUser) {
        throw { status: 400, message: '手机号已被占用' };
      }
    }

    // 更新修改时间
    updateData.updateTime = new Date();

    // 保存更新
    return await this.userRepository.save({ ...user, ...updateData });
  }

  /**
   * 禁用用户
   */
  async disableUser(id: string, currentUserId: string): Promise<boolean> {
    const user = await this.findById(id);
    if (!user) {
      return false;
    }

    user.status = UserStatus.DISABLED;
    user.updateTime = new Date();
    user.updatedBy = currentUserId;

    await this.userRepository.save(user);
    return true;
  }

  /**
   * 更新录取结果
   */
  async updateAdmissionResult(id: string, admissionResult: AdmissionResult): Promise<boolean> {
    // 开启事务
    const queryRunner = AppDataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      const user = await this.findById(id);
      if (!user) {
        return false;
      }

      // 更新用户录取结果
      user.admissionResult = admissionResult;
      user.updateTime = new Date();

      await this.userRepository.save(user);

      // 根据录取结果生成不同的消息内容
      let messageTitle = '';
      let messageContent = '';
      
      switch (admissionResult) {
        case AdmissionResult.ADMITTED:
          messageTitle = '恭喜您被录取！';
          messageContent = `尊敬的${user.name}同学，恭喜您被我校录取。请及时查看录取详情并完成后续手续。`;
          break;
        case AdmissionResult.REJECTED:
          messageTitle = '录取结果通知';
          messageContent = `尊敬的${user.name}同学，很遗憾地通知您，您未能被我校录取。感谢您的关注与支持。`;
          break;
        case AdmissionResult.WAITLISTED:
          messageTitle = '候补录取通知';
          messageContent = `尊敬的${user.name}同学，您目前处于候补录取状态，我们将在名额空缺时第一时间通知您。`;
          break;
        default:
          messageTitle = '录取状态更新';
          messageContent = `尊敬的${user.name}同学，您的录取状态已更新，请查看详情。`;
      }
      
      // 保存系统消息
      const systemMessage = new SystemMessage({
        title: messageTitle,
        content: messageContent,
        type: MessageType.ADMISSION,
        status: MessageStatus.UNREAD,
        userId: id,
        createTime: new Date(),
        updateTime: new Date()
      });
      
      await queryRunner.manager.save(SystemMessage, systemMessage);
      
      // 如果是录取或拒绝，发送微信模板消息通知
      if (admissionResult === AdmissionResult.ADMITTED || 
          admissionResult === AdmissionResult.REJECTED) {
        try {
          // 发送微信通知（异步执行，不等待结果）
          notificationService.sendAdmissionNotification(id).catch(error => {
            console.error('发送录取微信通知失败:', error);
          });
        } catch (notifyError) {
          console.error('发送录取通知失败:', notifyError);
          // 不影响主流程，继续提交事务
        }
      }
      
      // 提交事务
      await queryRunner.commitTransaction();
      return true;
    } catch (error) {
      // 回滚事务
      await queryRunner.rollbackTransaction();
      console.error('更新录取结果失败:', error);
      throw error;
    } finally {
      // 释放资源
      await queryRunner.release();
    }
  }

  /**
   * 通过录取
   */
  async admitUser(id: string, data: {
    admittedMajor: string;
    admissionBatch?: number;
    admissionResult: AdmissionResult;
    admissionTime: Date;
    admissionNoticePhoto: string;
  }): Promise<boolean> {
    // 开启事务
    const queryRunner = AppDataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      const user = await this.findById(id);
      if (!user) {
        return false;
      }

      user.admittedMajor = data.admittedMajor;
      user.admissionBatch = data.admissionBatch;
      user.admissionResult = data.admissionResult;
      user.admissionTime = data.admissionTime;
      user.admissionNoticePhoto = data.admissionNoticePhoto;
      user.updateTime = new Date();

      await this.userRepository.save(user);

      // 生成系统消息
      const batchText = user.admissionBatchText || '';
      const messageTitle = '恭喜您被录取！';
      const messageContent = `尊敬的${user.name}同学，恭喜您被我校${batchText}录取到${data.admittedMajor}专业。请及时查看录取详情并完成后续手续。`;
      
      // 保存系统消息
      const systemMessage = new SystemMessage({
        title: messageTitle,
        content: messageContent,
        type: MessageType.ADMISSION,
        status: MessageStatus.UNREAD,
        userId: id,
        createTime: new Date(),
        updateTime: new Date()
      });
      
      await queryRunner.manager.save(SystemMessage, systemMessage);
      
      // 发送微信模板消息通知（异步执行，不等待结果）
      try {
        // 检查用户的订阅状态
        if (user.subscriptionStatus === 1) { // 1表示已订阅
          // 处理专业名称，确保符合微信要求（short_thing3 类型限制为5个字符）
          const shortMajor = data.admittedMajor.length > 5 ? 
            data.admittedMajor.substring(0, 5) : 
            data.admittedMajor;
          
          console.log(`准备发送录取通知，专业名称: ${data.admittedMajor}，截断后: ${shortMajor}`);
          
          // 使用通知服务发送录取消息
          notificationService.sendAdmissionTemplateMessage(id, shortMajor)
            .catch((error: Error) => {
              console.error('发送录取微信通知失败:', error);
            });
          console.log(`已向用户 ${id} 发送录取微信通知`);
        } else {
          console.log(`用户 ${id} 未订阅消息，跳过发送微信通知`);
        }
      } catch (notifyError) {
        console.error('发送录取通知失败:', notifyError);
        // 不影响主流程，继续提交事务
      }
      
      // 提交事务
      await queryRunner.commitTransaction();
      return true;
    } catch (error) {
      // 回滚事务
      await queryRunner.rollbackTransaction();
      console.error('录取用户失败:', error);
      throw error;
    } finally {
      // 释放资源
      await queryRunner.release();
    }
  }

  /**
   * 更新缴费状态
   */
  async updatePaymentStatus(id: string, paymentStatus: PaymentStatus): Promise<boolean> {
    // 开启事务
    const queryRunner = AppDataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      const user = await this.findById(id);
      if (!user) {
        return false;
      }

      user.paymentStatus = paymentStatus;
      user.updateTime = new Date();

      await this.userRepository.save(user);

      // 生成系统消息
      let messageTitle = '';
      let messageContent = '';
      
      switch (paymentStatus) {
        case PaymentStatus.PAID:
          messageTitle = '缴费成功通知';
          messageContent = `尊敬的${user.name}同学，您的学费已缴纳成功。感谢您的支持！`;
          break;
        case PaymentStatus.PARTIAL:
          messageTitle = '部分缴费通知';
          messageContent = `尊敬的${user.name}同学，您已完成部分缴费，请尽快完成剩余款项的缴纳。`;
          break;
        case PaymentStatus.UNPAID:
          messageTitle = '缴费提醒';
          messageContent = `尊敬的${user.name}同学，请您尽快完成学费缴纳，以免影响入学。`;
          break;
      }
      
      // 保存系统消息
      const systemMessage = new SystemMessage({
        title: messageTitle,
        content: messageContent,
        type: MessageType.PAYMENT,
        status: MessageStatus.UNREAD,
        userId: id,
        createTime: new Date(),
        updateTime: new Date()
      });
      
      await queryRunner.manager.save(SystemMessage, systemMessage);
      
      // 如果是已缴费或部分缴费，发送微信模板消息通知
      if (paymentStatus !== PaymentStatus.UNPAID) {
        try {
          // 发送缴费状态更新的微信通知
          const amount = '详见系统'; // 这里可以传入实际金额
          const dueDate = ''; // 如果有截止日期可以传入
          
          notificationService.sendPaymentReminder(id, amount, dueDate).catch(error => {
            console.error('发送缴费微信通知失败:', error);
          });
        } catch (notifyError) {
          console.error('发送缴费通知失败:', notifyError);
          // 不影响主流程，继续提交事务
        }
      }
      
      // 提交事务
      await queryRunner.commitTransaction();
      return true;
    } catch (error) {
      // 回滚事务
      await queryRunner.rollbackTransaction();
      console.error('更新缴费状态失败:', error);
      throw error;
    } finally {
      // 释放资源
      await queryRunner.release();
    }
  }

  /**
   * 导出用户列表
   */
  async exportUsers(whereQuery: any = {}): Promise<any> {
    // 查询用户数据
    const users = await this.userRepository.find({
      where: whereQuery,
      order: { createTime: 'DESC' }
    });

    // 创建工作簿
    const workbook = new ExcelJS.Workbook();
    const worksheet = workbook.addWorksheet('用户列表');

    // 设置表头
    worksheet.columns = [
      { header: '用户ID', key: 'id', width: 20 },
      { header: '姓名', key: 'name', width: 15 },
      { header: '身份证号', key: 'idCard', width: 20 },
      { header: '性别', key: 'gender', width: 10 },
      { header: '手机号', key: 'mobile', width: 15 },
      { header: '省份', key: 'province', width: 15 },
      { header: '考试类型', key: 'examType', width: 15 },
      { header: '考号', key: 'examNumber', width: 15 },
      { header: '成绩', key: 'score', width: 10 },
      { header: '第一志愿', key: 'firstChoice', width: 20 },
      { header: '第二志愿', key: 'secondChoice', width: 20 },
      { header: '录取专业', key: 'admittedMajor', width: 20 },
      { header: '录取结果', key: 'admissionResult', width: 15 },
      { header: '缴费状态', key: 'paymentStatus', width: 15 },
      { header: '身份证照片', key: 'idCardFrontPhoto', width: 50 },
      { header: '准考证照片', key: 'admissionTicketPhoto', width: 50 },
      { header: '创建时间', key: 'createTime', width: 20 }
    ];

    // 添加数据行
    users.forEach(user => {
      worksheet.addRow({
        id: user.id,
        name: user.name,
        idCard: user.idCard,
        gender: user.genderText,
        mobile: user.mobile,
        province: user.province,
        examType: user.examType,
        examNumber: user.examNumber,
        score: user.score,
        firstChoice: user.firstChoice,
        secondChoice: user.secondChoice,
        admittedMajor: user.admittedMajor,
        admissionResult: user.admissionResultText,
        paymentStatus: user.paymentStatusText,
        idCardFrontPhoto: user.idCardFrontPhoto || '',
        admissionTicketPhoto: user.admissionTicketPhoto || '',
        createTime: user.createTime?.toLocaleString()
      });
    });

    // 设置表头样式
    worksheet.getRow(1).font = { bold: true };
    worksheet.getRow(1).alignment = { vertical: 'middle', horizontal: 'center' };

    // 导出为Buffer
    return await workbook.xlsx.writeBuffer();
  }

  /**
   * 按省份统计用户数量
   */
  async countUsersByProvince(): Promise<{province: string, count: number}[]> {
    const result = await this.userRepository
      .createQueryBuilder('user')
      .select('user.province', 'province')
      .addSelect('COUNT(user.id)', 'count')
      .where('user.province IS NOT NULL')
      .groupBy('user.province')
      .getRawMany();
    
        return result;
  }

  /**
   * 按录取结果统计用户数量
   */
  async countUsersByAdmissionResult(): Promise<{result: string, count: number}[]> {
    const rawResult = await this.userRepository
      .createQueryBuilder('user')
      .select('user.admissionResult', 'result')
      .addSelect('COUNT(user.id)', 'count')
      .groupBy('user.admissionResult')
      .getRawMany();
    
    // 转换结果
    return rawResult.map(item => {
      let resultText;
      switch (Number(item.result)) {
        case AdmissionResult.PENDING:
          resultText = '待录取';
          break;
        case AdmissionResult.ADMITTED:
          resultText = '已录取';
          break;
        case AdmissionResult.REJECTED:
          resultText = '未录取';
          break;
        case AdmissionResult.WAITLISTED:
          resultText = '候补';
          break;
        default:
          resultText = '未知';
      }
      
      return {
        result: resultText,
        count: Number(item.count)
      };
    });
  }
}
export const userService = new UserService(); 